/*
 * Copyright 2010-2020 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2010-2020 Ping Identity Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2010-2020 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses>.
 */
package com.unboundid.ldap.sdk.persist;



import java.util.Arrays;

import com.unboundid.ldap.sdk.DN;
import com.unboundid.ldap.sdk.Entry;
import com.unboundid.ldap.sdk.Filter;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPInterface;
import com.unboundid.ldap.sdk.ReadOnlyEntry;



/**
 * This class provides an implementation of an object that can be used to
 * represent inetOrgPerson objects in the directory.
 * It was generated by the generate-source-from-schema tool provided with the
 * UnboundID LDAP SDK for Java.  It may be customized as desired to better suit
 * your needs.
 */
@LDAPObject(structuralClass="inetOrgPerson",
            superiorClass={ "organizationalPerson",
                             "person",
                             "top" },
            defaultParentDN="ou=People,dc=example,dc=com",
            postDecodeMethod="doPostDecode",
            postEncodeMethod="doPostEncode")
public class TestInetOrgPerson
{
  /*
   * NOTE:  This class includes a number of annotation elements which are not
   * required but have been provided to make it easier to edit the resulting
   * source code.  If you want to exclude these unnecessary annotation
   * elements, use the '--terse' command-line argument.
   */



  // The field to use to hold a read-only copy of the associated entry.
  @LDAPEntryField()
  private ReadOnlyEntry ldapEntry;

  // The field used for RDN attribute uid.
  @LDAPField(attribute="uid",
             objectClass="inetOrgPerson",
             inRDN=true,
             filterUsage=FilterUsage.ALWAYS_ALLOWED,
             requiredForEncode=true)
  private String[] uid;

  // The field used for required attribute cn.
  @LDAPField(attribute="cn",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED,
             requiredForEncode=true)
  private String[] cn;

  // The field used for required attribute sn.
  @LDAPField(attribute="sn",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED,
             requiredForEncode=true)
  private String[] sn;

  // The field used for optional attribute audio.
  @LDAPField(attribute="audio",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private byte[][] audio;

  // The field used for optional attribute businessCategory.
  @LDAPField(attribute="businessCategory",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] businessCategory;

  // The field used for optional attribute carLicense.
  @LDAPField(attribute="carLicense",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] carLicense;

  // The field used for optional attribute departmentNumber.
  @LDAPField(attribute="departmentNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] departmentNumber;

  // The field used for optional attribute description.
  @LDAPField(attribute="description",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] description;

  // The field used for optional attribute destinationIndicator.
  @LDAPField(attribute="destinationIndicator",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] destinationIndicator;

  // The field used for optional attribute displayName.
  @LDAPField(attribute="displayName",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String displayName;

  // The field used for optional attribute employeeNumber.
  @LDAPField(attribute="employeeNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String employeeNumber;

  // The field used for optional attribute employeeType.
  @LDAPField(attribute="employeeType",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] employeeType;

  // The field used for optional attribute facsimileTelephoneNumber.
  @LDAPField(attribute="facsimileTelephoneNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] facsimileTelephoneNumber;

  // The field used for optional attribute givenName.
  @LDAPField(attribute="givenName",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] givenName;

  // The field used for optional attribute homePhone.
  @LDAPField(attribute="homePhone",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] homePhone;

  // The field used for optional attribute homePostalAddress.
  @LDAPField(attribute="homePostalAddress",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] homePostalAddress;

  // The field used for optional attribute initials.
  @LDAPField(attribute="initials",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] initials;

  // The field used for optional attribute internationaliSDNNumber.
  @LDAPField(attribute="internationaliSDNNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] internationaliSDNNumber;

  // The field used for optional attribute jpegPhoto.
  @LDAPField(attribute="jpegPhoto",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private byte[][] jpegPhoto;

  // The field used for optional attribute l.
  @LDAPField(attribute="l",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] l;

  // The field used for optional attribute labeledURI.
  @LDAPField(attribute="labeledURI",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] labeledURI;

  // The field used for optional attribute mail.
  @LDAPField(attribute="mail",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] mail;

  // The field used for optional attribute manager.
  @LDAPField(attribute="manager",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private DN[] manager;

  // The field used for optional attribute mobile.
  @LDAPField(attribute="mobile",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] mobile;

  // The field used for optional attribute o.
  @LDAPField(attribute="o",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] o;

  // The field used for optional attribute ou.
  @LDAPField(attribute="ou",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] ou;

  // The field used for optional attribute pager.
  @LDAPField(attribute="pager",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] pager;

  // The field used for optional attribute photo.
  @LDAPField(attribute="photo",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private byte[][] photo;

  // The field used for optional attribute physicalDeliveryOfficeName.
  @LDAPField(attribute="physicalDeliveryOfficeName",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] physicalDeliveryOfficeName;

  // The field used for optional attribute postalAddress.
  @LDAPField(attribute="postalAddress",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] postalAddress;

  // The field used for optional attribute postalCode.
  @LDAPField(attribute="postalCode",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] postalCode;

  // The field used for optional attribute postOfficeBox.
  @LDAPField(attribute="postOfficeBox",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] postOfficeBox;

  // The field used for optional attribute preferredDeliveryMethod.
  @LDAPField(attribute="preferredDeliveryMethod",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String preferredDeliveryMethod;

  // The field used for optional attribute preferredLanguage.
  @LDAPField(attribute="preferredLanguage",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String preferredLanguage;

  // The field used for optional attribute registeredAddress.
  @LDAPField(attribute="registeredAddress",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] registeredAddress;

  // The field used for optional attribute roomNumber.
  @LDAPField(attribute="roomNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] roomNumber;

  // The field used for optional attribute secretary.
  @LDAPField(attribute="secretary",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private DN[] secretary;

  // The field used for optional attribute seeAlso.
  @LDAPField(attribute="seeAlso",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private DN[] seeAlso;

  // The field used for optional attribute st.
  @LDAPField(attribute="st",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] st;

  // The field used for optional attribute street.
  @LDAPField(attribute="street",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] street;

  // The field used for optional attribute telephoneNumber.
  @LDAPField(attribute="telephoneNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] telephoneNumber;

  // The field used for optional attribute teletexTerminalIdentifier.
  @LDAPField(attribute="teletexTerminalIdentifier",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] teletexTerminalIdentifier;

  // The field used for optional attribute telexNumber.
  @LDAPField(attribute="telexNumber",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] telexNumber;

  // The field used for optional attribute title.
  @LDAPField(attribute="title",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] title;

  // The field used for optional attribute userCertificate.
  @LDAPField(attribute="userCertificate",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private byte[][] userCertificate;

  // The field used for optional attribute userPassword.
  @LDAPField(attribute="userPassword",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] userPassword;

  // The field used for optional attribute userPKCS12.
  @LDAPField(attribute="userPKCS12",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private byte[][] userPKCS12;

  // The field used for optional attribute userSMIMECertificate.
  @LDAPField(attribute="userSMIMECertificate",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private byte[][] userSMIMECertificate;

  // The field used for optional attribute x121Address.
  @LDAPField(attribute="x121Address",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] x121Address;

  // The field used for optional attribute x500UniqueIdentifier.
  @LDAPField(attribute="x500UniqueIdentifier",
             objectClass="inetOrgPerson",
             filterUsage=FilterUsage.CONDITIONALLY_ALLOWED)
  private String[] x500UniqueIdentifier;



  /**
   * Creates a new instance of this object.  All fields will be uninitialized,
   * so the setter methods should be used to assign values to them.
   */
  public TestInetOrgPerson()
  {
    // No initialization will be performed by default.  Note that if you set
    // values for any fields marked with an @LDAPField, @LDAPDNField, or
    // @LDAPEntryField annotation, they will be overwritten in the course of
    // decoding initializing this object from an LDAP entry.
  }



  /**
   * Creates a new TestInetOrgPerson object decoded
   * from the provided entry.
   *
   * @param  entry  The entry to be decoded.
   *
   * @return  The decoded TestInetOrgPerson object.
   *
   * @throws  LDAPPersistException  If a problem occurs while attempting to
   *                                decode the provided entry.
   */
  public static TestInetOrgPerson decode(final Entry entry)
         throws LDAPPersistException
  {
    return getPersister().decode(entry);
  }



  /**
   * Retrieves an {@code LDAPPersister} instance that may be used to interact
   * with objects of this type.
   *
   * @return  An {@code LDAPPersister} instance that may be used to interact
   *          with objects of this type.
   *
   * @throws  LDAPPersistException  If a problem occurs while creating the
   *                                {@code LDAPPersister} instance.
   */
  public static LDAPPersister<TestInetOrgPerson> getPersister()
         throws LDAPPersistException
  {
    return LDAPPersister.getInstance(TestInetOrgPerson.class);
  }



  /**
   * Performs any processing that may be necessary after initializing this
   * object from an LDAP entry.
   *
   * @throws  LDAPPersistException  If the generated entry should not be used.
   */
  private void doPostDecode()
          throws LDAPPersistException
  {
    // No processing is needed by default.  You may provide an implementation
    // for this method if custom post-decode processing is needed.
  }



  /**
   * Performs any processing that may be necessary after encoding this object
   * to an LDAP entry.
   *
   * @param  entry  The entry that has been generated.  It may be altered if
   *                desired.
   *
   * @throws  LDAPPersistException  If there is a problem with the object after
   *                                it has been decoded from an LDAP entry.
   */
  private void doPostEncode(final Entry entry)
          throws LDAPPersistException
  {
    // No processing is needed by default.  You may provide an implementation
    // for this method if custom post-encode processing is needed.
  }



  /**
   * Retrieves a read-only copy of the entry with which this object is
   * associated, if it is available.  It will only be available if this object
   * was decoded from or encoded to an LDAP entry.
   *
   * @return  A read-only copy of the entry with which this object is
   *          associated, or {@code null} if it is not available.
   */
  public ReadOnlyEntry getLDAPEntry()
  {
    return ldapEntry;
  }



  /**
   * Retrieves the DN of the entry with which this object is associated, if it
   * is available.  It will only be available if this object was decoded from or
   * encoded to an LDAP entry.
   *
   * @return  The DN of the entry with which this object is associated, or
   *          {@code null} if it is not available.
   */
  public String getLDAPEntryDN()
  {
    if (ldapEntry == null)
    {
      return null;
    }
    else
    {
      return ldapEntry.getDN();
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * uid attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          uid attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstUid()
  {
    if ((uid == null) ||
        (uid.length == 0))
    {
      return null;
    }
    else
    {
      return uid[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * uid attribute, if present.
   *
   * @return  The values for the field associated with the
   *          uid attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getUid()
  {
    return uid;
  }



  /**
   * Sets the values for the field associated with the
   * uid attribute.
   *
   * @param  v  The values for the field associated with the
   *            uid attribute.
   */
  public void setUid(final String... v)
  {
    this.uid = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the uid attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateUidFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "uid");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "uid");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "uid").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "uid");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "uid",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "uid",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "uid",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "uid",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "uid",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "uid",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "uid",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * cn attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          cn attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstCn()
  {
    if ((cn == null) ||
        (cn.length == 0))
    {
      return null;
    }
    else
    {
      return cn[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * cn attribute, if present.
   *
   * @return  The values for the field associated with the
   *          cn attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getCn()
  {
    return cn;
  }



  /**
   * Sets the values for the field associated with the
   * cn attribute.
   *
   * @param  v  The values for the field associated with the
   *            cn attribute.
   */
  public void setCn(final String... v)
  {
    this.cn = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the cn attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateCnFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "cn");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "cn");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "cn").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "cn");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "cn",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "cn",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "cn",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "cn",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "cn",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "cn",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "cn",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * sn attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          sn attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstSn()
  {
    if ((sn == null) ||
        (sn.length == 0))
    {
      return null;
    }
    else
    {
      return sn[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * sn attribute, if present.
   *
   * @return  The values for the field associated with the
   *          sn attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getSn()
  {
    return sn;
  }



  /**
   * Sets the values for the field associated with the
   * sn attribute.
   *
   * @param  v  The values for the field associated with the
   *            sn attribute.
   */
  public void setSn(final String... v)
  {
    this.sn = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the sn attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateSnFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "sn");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "sn");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "sn").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "sn");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "sn",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "sn",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "sn",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "sn",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "sn",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "sn",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "sn",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * audio attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          audio attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public byte[] getFirstAudio()
  {
    if ((audio == null) ||
        (audio.length == 0))
    {
      return null;
    }
    else
    {
      return audio[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * audio attribute, if present.
   *
   * @return  The values for the field associated with the
   *          audio attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public byte[][] getAudio()
  {
    return audio;
  }



  /**
   * Sets the values for the field associated with the
   * audio attribute.
   *
   * @param  v  The values for the field associated with the
   *            audio attribute.
   */
  public void setAudio(final byte[]... v)
  {
    this.audio = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the audio attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateAudioFilter(
                            final PersistFilterType filterType,
                            final byte[] value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "audio");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "audio");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new byte[][] { value },
           "audio").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "audio");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "audio",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "audio",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "audio",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "audio",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "audio",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "audio",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "audio",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * businessCategory attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          businessCategory attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstBusinessCategory()
  {
    if ((businessCategory == null) ||
        (businessCategory.length == 0))
    {
      return null;
    }
    else
    {
      return businessCategory[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * businessCategory attribute, if present.
   *
   * @return  The values for the field associated with the
   *          businessCategory attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getBusinessCategory()
  {
    return businessCategory;
  }



  /**
   * Sets the values for the field associated with the
   * businessCategory attribute.
   *
   * @param  v  The values for the field associated with the
   *            businessCategory attribute.
   */
  public void setBusinessCategory(final String... v)
  {
    this.businessCategory = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the businessCategory attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateBusinessCategoryFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "businessCategory");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "businesscategory");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "businessCategory").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "businessCategory");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "businessCategory",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "businessCategory",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "businessCategory",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "businessCategory",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "businessCategory",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "businessCategory",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "businessCategory",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * carLicense attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          carLicense attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstCarLicense()
  {
    if ((carLicense == null) ||
        (carLicense.length == 0))
    {
      return null;
    }
    else
    {
      return carLicense[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * carLicense attribute, if present.
   *
   * @return  The values for the field associated with the
   *          carLicense attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getCarLicense()
  {
    return carLicense;
  }



  /**
   * Sets the values for the field associated with the
   * carLicense attribute.
   *
   * @param  v  The values for the field associated with the
   *            carLicense attribute.
   */
  public void setCarLicense(final String... v)
  {
    this.carLicense = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the carLicense attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateCarLicenseFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "carLicense");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "carlicense");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "carLicense").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "carLicense");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "carLicense",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "carLicense",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "carLicense",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "carLicense",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "carLicense",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "carLicense",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "carLicense",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * departmentNumber attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          departmentNumber attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstDepartmentNumber()
  {
    if ((departmentNumber == null) ||
        (departmentNumber.length == 0))
    {
      return null;
    }
    else
    {
      return departmentNumber[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * departmentNumber attribute, if present.
   *
   * @return  The values for the field associated with the
   *          departmentNumber attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getDepartmentNumber()
  {
    return departmentNumber;
  }



  /**
   * Sets the values for the field associated with the
   * departmentNumber attribute.
   *
   * @param  v  The values for the field associated with the
   *            departmentNumber attribute.
   */
  public void setDepartmentNumber(final String... v)
  {
    this.departmentNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the departmentNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateDepartmentNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "departmentNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "departmentnumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "departmentNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "departmentNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "departmentNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "departmentNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "departmentNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "departmentNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "departmentNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "departmentNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "departmentNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * description attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          description attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstDescription()
  {
    if ((description == null) ||
        (description.length == 0))
    {
      return null;
    }
    else
    {
      return description[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * description attribute, if present.
   *
   * @return  The values for the field associated with the
   *          description attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getDescription()
  {
    return description;
  }



  /**
   * Sets the values for the field associated with the
   * description attribute.
   *
   * @param  v  The values for the field associated with the
   *            description attribute.
   */
  public void setDescription(final String... v)
  {
    this.description = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the description attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateDescriptionFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "description");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "description");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "description").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "description");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "description",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "description",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "description",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "description",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "description",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "description",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "description",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * destinationIndicator attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          destinationIndicator attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstDestinationIndicator()
  {
    if ((destinationIndicator == null) ||
        (destinationIndicator.length == 0))
    {
      return null;
    }
    else
    {
      return destinationIndicator[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * destinationIndicator attribute, if present.
   *
   * @return  The values for the field associated with the
   *          destinationIndicator attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getDestinationIndicator()
  {
    return destinationIndicator;
  }



  /**
   * Sets the values for the field associated with the
   * destinationIndicator attribute.
   *
   * @param  v  The values for the field associated with the
   *            destinationIndicator attribute.
   */
  public void setDestinationIndicator(final String... v)
  {
    this.destinationIndicator = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the destinationIndicator attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateDestinationIndicatorFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "destinationIndicator");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "destinationindicator");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "destinationIndicator").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "destinationIndicator");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "destinationIndicator",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "destinationIndicator",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "destinationIndicator",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "destinationIndicator",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "destinationIndicator",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "destinationIndicator",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "destinationIndicator",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the value for the field associated with the
   * displayName attribute, if present.
   *
   * @return  The value for the field associated with the
   *          displayName attribute, or
   *          {@code null} if the field does not have a value.
   */
  public String getDisplayName()
  {
    return displayName;
  }



  /**
   * Sets the value for the field associated with the
   * displayName attribute.
   *
   * @param  v  The value for the field associated with the
   *            displayName attribute.
   */
  public void setDisplayName(final String v)
  {
    this.displayName = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the displayName attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateDisplayNameFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "displayName");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "displayname");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           value,
           "displayName").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "displayName");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "displayName",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "displayName",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "displayName",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "displayName",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "displayName",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "displayName",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "displayName",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the value for the field associated with the
   * employeeNumber attribute, if present.
   *
   * @return  The value for the field associated with the
   *          employeeNumber attribute, or
   *          {@code null} if the field does not have a value.
   */
  public String getEmployeeNumber()
  {
    return employeeNumber;
  }



  /**
   * Sets the value for the field associated with the
   * employeeNumber attribute.
   *
   * @param  v  The value for the field associated with the
   *            employeeNumber attribute.
   */
  public void setEmployeeNumber(final String v)
  {
    this.employeeNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the employeeNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateEmployeeNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "employeeNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "employeenumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           value,
           "employeeNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "employeeNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "employeeNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "employeeNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "employeeNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "employeeNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "employeeNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "employeeNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "employeeNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * employeeType attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          employeeType attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstEmployeeType()
  {
    if ((employeeType == null) ||
        (employeeType.length == 0))
    {
      return null;
    }
    else
    {
      return employeeType[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * employeeType attribute, if present.
   *
   * @return  The values for the field associated with the
   *          employeeType attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getEmployeeType()
  {
    return employeeType;
  }



  /**
   * Sets the values for the field associated with the
   * employeeType attribute.
   *
   * @param  v  The values for the field associated with the
   *            employeeType attribute.
   */
  public void setEmployeeType(final String... v)
  {
    this.employeeType = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the employeeType attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateEmployeeTypeFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "employeeType");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "employeetype");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "employeeType").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "employeeType");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "employeeType",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "employeeType",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "employeeType",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "employeeType",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "employeeType",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "employeeType",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "employeeType",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * facsimileTelephoneNumber attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          facsimileTelephoneNumber attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstFacsimileTelephoneNumber()
  {
    if ((facsimileTelephoneNumber == null) ||
        (facsimileTelephoneNumber.length == 0))
    {
      return null;
    }
    else
    {
      return facsimileTelephoneNumber[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * facsimileTelephoneNumber attribute, if present.
   *
   * @return  The values for the field associated with the
   *          facsimileTelephoneNumber attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getFacsimileTelephoneNumber()
  {
    return facsimileTelephoneNumber;
  }



  /**
   * Sets the values for the field associated with the
   * facsimileTelephoneNumber attribute.
   *
   * @param  v  The values for the field associated with the
   *            facsimileTelephoneNumber attribute.
   */
  public void setFacsimileTelephoneNumber(final String... v)
  {
    this.facsimileTelephoneNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the facsimileTelephoneNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateFacsimileTelephoneNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "facsimileTelephoneNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "facsimiletelephonenumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "facsimileTelephoneNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "facsimileTelephoneNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "facsimileTelephoneNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "facsimileTelephoneNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "facsimileTelephoneNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "facsimileTelephoneNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "facsimileTelephoneNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "facsimileTelephoneNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "facsimileTelephoneNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * givenName attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          givenName attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstGivenName()
  {
    if ((givenName == null) ||
        (givenName.length == 0))
    {
      return null;
    }
    else
    {
      return givenName[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * givenName attribute, if present.
   *
   * @return  The values for the field associated with the
   *          givenName attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getGivenName()
  {
    return givenName;
  }



  /**
   * Sets the values for the field associated with the
   * givenName attribute.
   *
   * @param  v  The values for the field associated with the
   *            givenName attribute.
   */
  public void setGivenName(final String... v)
  {
    this.givenName = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the givenName attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateGivenNameFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "givenName");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "givenname");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "givenName").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "givenName");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "givenName",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "givenName",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "givenName",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "givenName",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "givenName",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "givenName",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "givenName",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * homePhone attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          homePhone attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstHomePhone()
  {
    if ((homePhone == null) ||
        (homePhone.length == 0))
    {
      return null;
    }
    else
    {
      return homePhone[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * homePhone attribute, if present.
   *
   * @return  The values for the field associated with the
   *          homePhone attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getHomePhone()
  {
    return homePhone;
  }



  /**
   * Sets the values for the field associated with the
   * homePhone attribute.
   *
   * @param  v  The values for the field associated with the
   *            homePhone attribute.
   */
  public void setHomePhone(final String... v)
  {
    this.homePhone = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the homePhone attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateHomePhoneFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "homePhone");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "homephone");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "homePhone").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "homePhone");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "homePhone",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "homePhone",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "homePhone",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "homePhone",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "homePhone",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "homePhone",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "homePhone",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * homePostalAddress attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          homePostalAddress attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstHomePostalAddress()
  {
    if ((homePostalAddress == null) ||
        (homePostalAddress.length == 0))
    {
      return null;
    }
    else
    {
      return homePostalAddress[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * homePostalAddress attribute, if present.
   *
   * @return  The values for the field associated with the
   *          homePostalAddress attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getHomePostalAddress()
  {
    return homePostalAddress;
  }



  /**
   * Sets the values for the field associated with the
   * homePostalAddress attribute.
   *
   * @param  v  The values for the field associated with the
   *            homePostalAddress attribute.
   */
  public void setHomePostalAddress(final String... v)
  {
    this.homePostalAddress = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the homePostalAddress attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateHomePostalAddressFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "homePostalAddress");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "homepostaladdress");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "homePostalAddress").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "homePostalAddress");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "homePostalAddress",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "homePostalAddress",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "homePostalAddress",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "homePostalAddress",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "homePostalAddress",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "homePostalAddress",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "homePostalAddress",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * initials attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          initials attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstInitials()
  {
    if ((initials == null) ||
        (initials.length == 0))
    {
      return null;
    }
    else
    {
      return initials[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * initials attribute, if present.
   *
   * @return  The values for the field associated with the
   *          initials attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getInitials()
  {
    return initials;
  }



  /**
   * Sets the values for the field associated with the
   * initials attribute.
   *
   * @param  v  The values for the field associated with the
   *            initials attribute.
   */
  public void setInitials(final String... v)
  {
    this.initials = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the initials attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateInitialsFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "initials");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "initials");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "initials").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "initials");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "initials",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "initials",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "initials",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "initials",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "initials",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "initials",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "initials",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * internationaliSDNNumber attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          internationaliSDNNumber attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstInternationaliSDNNumber()
  {
    if ((internationaliSDNNumber == null) ||
        (internationaliSDNNumber.length == 0))
    {
      return null;
    }
    else
    {
      return internationaliSDNNumber[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * internationaliSDNNumber attribute, if present.
   *
   * @return  The values for the field associated with the
   *          internationaliSDNNumber attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getInternationaliSDNNumber()
  {
    return internationaliSDNNumber;
  }



  /**
   * Sets the values for the field associated with the
   * internationaliSDNNumber attribute.
   *
   * @param  v  The values for the field associated with the
   *            internationaliSDNNumber attribute.
   */
  public void setInternationaliSDNNumber(final String... v)
  {
    this.internationaliSDNNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the internationaliSDNNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateInternationaliSDNNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "internationaliSDNNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "internationalisdnnumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "internationaliSDNNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "internationaliSDNNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "internationaliSDNNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "internationaliSDNNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "internationaliSDNNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "internationaliSDNNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "internationaliSDNNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "internationaliSDNNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "internationaliSDNNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * jpegPhoto attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          jpegPhoto attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public byte[] getFirstJpegPhoto()
  {
    if ((jpegPhoto == null) ||
        (jpegPhoto.length == 0))
    {
      return null;
    }
    else
    {
      return jpegPhoto[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * jpegPhoto attribute, if present.
   *
   * @return  The values for the field associated with the
   *          jpegPhoto attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public byte[][] getJpegPhoto()
  {
    return jpegPhoto;
  }



  /**
   * Sets the values for the field associated with the
   * jpegPhoto attribute.
   *
   * @param  v  The values for the field associated with the
   *            jpegPhoto attribute.
   */
  public void setJpegPhoto(final byte[]... v)
  {
    this.jpegPhoto = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the jpegPhoto attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateJpegPhotoFilter(
                            final PersistFilterType filterType,
                            final byte[] value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "jpegPhoto");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "jpegphoto");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new byte[][] { value },
           "jpegPhoto").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "jpegPhoto");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "jpegPhoto",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "jpegPhoto",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "jpegPhoto",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "jpegPhoto",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "jpegPhoto",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "jpegPhoto",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "jpegPhoto",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * l attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          l attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstL()
  {
    if ((l == null) ||
        (l.length == 0))
    {
      return null;
    }
    else
    {
      return l[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * l attribute, if present.
   *
   * @return  The values for the field associated with the
   *          l attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getL()
  {
    return l;
  }



  /**
   * Sets the values for the field associated with the
   * l attribute.
   *
   * @param  v  The values for the field associated with the
   *            l attribute.
   */
  public void setL(final String... v)
  {
    this.l = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the l attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateLFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "l");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "l");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "l").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "l");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "l",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "l",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "l",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "l",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "l",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "l",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "l",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * labeledURI attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          labeledURI attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstLabeledURI()
  {
    if ((labeledURI == null) ||
        (labeledURI.length == 0))
    {
      return null;
    }
    else
    {
      return labeledURI[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * labeledURI attribute, if present.
   *
   * @return  The values for the field associated with the
   *          labeledURI attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getLabeledURI()
  {
    return labeledURI;
  }



  /**
   * Sets the values for the field associated with the
   * labeledURI attribute.
   *
   * @param  v  The values for the field associated with the
   *            labeledURI attribute.
   */
  public void setLabeledURI(final String... v)
  {
    this.labeledURI = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the labeledURI attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateLabeledURIFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "labeledURI");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "labeleduri");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "labeledURI").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "labeledURI");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "labeledURI",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "labeledURI",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "labeledURI",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "labeledURI",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "labeledURI",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "labeledURI",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "labeledURI",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * mail attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          mail attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstMail()
  {
    if ((mail == null) ||
        (mail.length == 0))
    {
      return null;
    }
    else
    {
      return mail[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * mail attribute, if present.
   *
   * @return  The values for the field associated with the
   *          mail attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getMail()
  {
    return mail;
  }



  /**
   * Sets the values for the field associated with the
   * mail attribute.
   *
   * @param  v  The values for the field associated with the
   *            mail attribute.
   */
  public void setMail(final String... v)
  {
    this.mail = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the mail attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateMailFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "mail");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "mail");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "mail").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "mail");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "mail",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "mail",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "mail",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "mail",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "mail",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "mail",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "mail",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * manager attribute as a DN, if present.
   *
   * @return  The first value for the field associated with the
   *          manager attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public DN getFirstManagerDN()
  {
    if ((manager == null) ||
        (manager.length == 0))
    {
      return null;
    }
    else
    {
      return manager[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * manager attribute as DNs, if present.
   *
   * @return  The values for the field associated with the
   *          manager attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public DN[] getManagerDNs()
  {
    return manager;
  }



  /**
   * Retrieves the values for the field associated with the
   * manager attribute as objects of the specified type,
   * if present.
   *
   * @param  <T>  The type of object to return.
   *
   * @param  connection  The connection to use to retrieve the entries.  It
   *                     must not be {@code null}.
   * @param  type        The type of object as which the entries should be
   *                     decoded.  It must not be {@code null}, and the class
   *                     must be marked with the {@code LDAPObject} annotation
   *                     type.
   *
   * @return  A {@code PersistedObjects} object that may be used to iterate
   *          across the resulting objects.
   *
   * @throws  LDAPException  If the requested type cannot be used with the LDAP
   *                         SDK persistence framework.
   */
  public <T> PersistedObjects<T> getManagerObjects(
                                      final LDAPInterface connection,
                                      final Class<T> type)
         throws LDAPException
  {
    return PersistUtils.getEntriesAsObjects(manager,
         type, connection);
  }



  /**
   * Sets the values for the field associated with the
   * manager attribute.
   *
   * @param  v  The values for the field associated with the
   *            manager attribute.
   */
  public void setManager(final DN... v)
  {
    this.manager = v;
  }



  /**
   * Sets the values for the field associated with the
   * manager attribute.
   *
   * @param  v  The string representations of the values for the field
   *            associated with the manager attribute.
   *
   * @throws  LDAPException  If any of the provided strings cannot be parsed as
   *                         a DN.
   */
  public void setManager(final String... v)
         throws LDAPException
  {
    if (v == null)
    {
      this.manager = null;
    }
    else
    {
      this.manager = new DN[v.length];
      for (int i=0; i < v.length; i++)
      {
        this.manager[i] = new DN(v[i]);
      }
    }
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the manager attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateManagerFilter(
                            final PersistFilterType filterType,
                            final DN value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "manager");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "manager");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new DN[] { value },
           "manager").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "manager");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "manager",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "manager",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "manager",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "manager",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "manager",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "manager",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "manager",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * mobile attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          mobile attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstMobile()
  {
    if ((mobile == null) ||
        (mobile.length == 0))
    {
      return null;
    }
    else
    {
      return mobile[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * mobile attribute, if present.
   *
   * @return  The values for the field associated with the
   *          mobile attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getMobile()
  {
    return mobile;
  }



  /**
   * Sets the values for the field associated with the
   * mobile attribute.
   *
   * @param  v  The values for the field associated with the
   *            mobile attribute.
   */
  public void setMobile(final String... v)
  {
    this.mobile = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the mobile attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateMobileFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "mobile");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "mobile");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "mobile").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "mobile");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "mobile",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "mobile",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "mobile",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "mobile",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "mobile",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "mobile",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "mobile",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * o attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          o attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstO()
  {
    if ((o == null) ||
        (o.length == 0))
    {
      return null;
    }
    else
    {
      return o[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * o attribute, if present.
   *
   * @return  The values for the field associated with the
   *          o attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getO()
  {
    return o;
  }



  /**
   * Sets the values for the field associated with the
   * o attribute.
   *
   * @param  v  The values for the field associated with the
   *            o attribute.
   */
  public void setO(final String... v)
  {
    this.o = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the o attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateOFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "o");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "o");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "o").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "o");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "o",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "o",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "o",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "o",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "o",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "o",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "o",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * ou attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          ou attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstOu()
  {
    if ((ou == null) ||
        (ou.length == 0))
    {
      return null;
    }
    else
    {
      return ou[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * ou attribute, if present.
   *
   * @return  The values for the field associated with the
   *          ou attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getOu()
  {
    return ou;
  }



  /**
   * Sets the values for the field associated with the
   * ou attribute.
   *
   * @param  v  The values for the field associated with the
   *            ou attribute.
   */
  public void setOu(final String... v)
  {
    this.ou = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the ou attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateOuFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "ou");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "ou");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "ou").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "ou");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "ou",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "ou",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "ou",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "ou",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "ou",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "ou",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "ou",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * pager attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          pager attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstPager()
  {
    if ((pager == null) ||
        (pager.length == 0))
    {
      return null;
    }
    else
    {
      return pager[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * pager attribute, if present.
   *
   * @return  The values for the field associated with the
   *          pager attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getPager()
  {
    return pager;
  }



  /**
   * Sets the values for the field associated with the
   * pager attribute.
   *
   * @param  v  The values for the field associated with the
   *            pager attribute.
   */
  public void setPager(final String... v)
  {
    this.pager = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the pager attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePagerFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "pager");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "pager");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "pager").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "pager");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "pager",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "pager",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "pager",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "pager",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "pager",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "pager",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "pager",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * photo attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          photo attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public byte[] getFirstPhoto()
  {
    if ((photo == null) ||
        (photo.length == 0))
    {
      return null;
    }
    else
    {
      return photo[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * photo attribute, if present.
   *
   * @return  The values for the field associated with the
   *          photo attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public byte[][] getPhoto()
  {
    return photo;
  }



  /**
   * Sets the values for the field associated with the
   * photo attribute.
   *
   * @param  v  The values for the field associated with the
   *            photo attribute.
   */
  public void setPhoto(final byte[]... v)
  {
    this.photo = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the photo attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePhotoFilter(
                            final PersistFilterType filterType,
                            final byte[] value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "photo");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "photo");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new byte[][] { value },
           "photo").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "photo");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "photo",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "photo",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "photo",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "photo",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "photo",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "photo",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "photo",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * physicalDeliveryOfficeName attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          physicalDeliveryOfficeName attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstPhysicalDeliveryOfficeName()
  {
    if ((physicalDeliveryOfficeName == null) ||
        (physicalDeliveryOfficeName.length == 0))
    {
      return null;
    }
    else
    {
      return physicalDeliveryOfficeName[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * physicalDeliveryOfficeName attribute, if present.
   *
   * @return  The values for the field associated with the
   *          physicalDeliveryOfficeName attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getPhysicalDeliveryOfficeName()
  {
    return physicalDeliveryOfficeName;
  }



  /**
   * Sets the values for the field associated with the
   * physicalDeliveryOfficeName attribute.
   *
   * @param  v  The values for the field associated with the
   *            physicalDeliveryOfficeName attribute.
   */
  public void setPhysicalDeliveryOfficeName(final String... v)
  {
    this.physicalDeliveryOfficeName = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the physicalDeliveryOfficeName attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePhysicalDeliveryOfficeNameFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "physicalDeliveryOfficeName");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "physicaldeliveryofficename");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "physicalDeliveryOfficeName").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "physicalDeliveryOfficeName");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "physicalDeliveryOfficeName",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "physicalDeliveryOfficeName",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "physicalDeliveryOfficeName",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "physicalDeliveryOfficeName",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "physicalDeliveryOfficeName",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "physicalDeliveryOfficeName",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "physicalDeliveryOfficeName",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * postalAddress attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          postalAddress attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstPostalAddress()
  {
    if ((postalAddress == null) ||
        (postalAddress.length == 0))
    {
      return null;
    }
    else
    {
      return postalAddress[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * postalAddress attribute, if present.
   *
   * @return  The values for the field associated with the
   *          postalAddress attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getPostalAddress()
  {
    return postalAddress;
  }



  /**
   * Sets the values for the field associated with the
   * postalAddress attribute.
   *
   * @param  v  The values for the field associated with the
   *            postalAddress attribute.
   */
  public void setPostalAddress(final String... v)
  {
    this.postalAddress = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the postalAddress attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePostalAddressFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "postalAddress");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "postaladdress");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "postalAddress").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "postalAddress");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "postalAddress",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "postalAddress",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "postalAddress",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "postalAddress",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "postalAddress",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "postalAddress",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "postalAddress",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * postalCode attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          postalCode attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstPostalCode()
  {
    if ((postalCode == null) ||
        (postalCode.length == 0))
    {
      return null;
    }
    else
    {
      return postalCode[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * postalCode attribute, if present.
   *
   * @return  The values for the field associated with the
   *          postalCode attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getPostalCode()
  {
    return postalCode;
  }



  /**
   * Sets the values for the field associated with the
   * postalCode attribute.
   *
   * @param  v  The values for the field associated with the
   *            postalCode attribute.
   */
  public void setPostalCode(final String... v)
  {
    this.postalCode = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the postalCode attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePostalCodeFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "postalCode");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "postalcode");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "postalCode").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "postalCode");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "postalCode",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "postalCode",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "postalCode",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "postalCode",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "postalCode",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "postalCode",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "postalCode",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * postOfficeBox attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          postOfficeBox attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstPostOfficeBox()
  {
    if ((postOfficeBox == null) ||
        (postOfficeBox.length == 0))
    {
      return null;
    }
    else
    {
      return postOfficeBox[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * postOfficeBox attribute, if present.
   *
   * @return  The values for the field associated with the
   *          postOfficeBox attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getPostOfficeBox()
  {
    return postOfficeBox;
  }



  /**
   * Sets the values for the field associated with the
   * postOfficeBox attribute.
   *
   * @param  v  The values for the field associated with the
   *            postOfficeBox attribute.
   */
  public void setPostOfficeBox(final String... v)
  {
    this.postOfficeBox = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the postOfficeBox attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePostOfficeBoxFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "postOfficeBox");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "postofficebox");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "postOfficeBox").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "postOfficeBox");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "postOfficeBox",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "postOfficeBox",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "postOfficeBox",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "postOfficeBox",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "postOfficeBox",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "postOfficeBox",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "postOfficeBox",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the value for the field associated with the
   * preferredDeliveryMethod attribute, if present.
   *
   * @return  The value for the field associated with the
   *          preferredDeliveryMethod attribute, or
   *          {@code null} if the field does not have a value.
   */
  public String getPreferredDeliveryMethod()
  {
    return preferredDeliveryMethod;
  }



  /**
   * Sets the value for the field associated with the
   * preferredDeliveryMethod attribute.
   *
   * @param  v  The value for the field associated with the
   *            preferredDeliveryMethod attribute.
   */
  public void setPreferredDeliveryMethod(final String v)
  {
    this.preferredDeliveryMethod = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the preferredDeliveryMethod attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePreferredDeliveryMethodFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "preferredDeliveryMethod");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "preferreddeliverymethod");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           value,
           "preferredDeliveryMethod").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "preferredDeliveryMethod");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "preferredDeliveryMethod",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "preferredDeliveryMethod",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "preferredDeliveryMethod",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "preferredDeliveryMethod",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "preferredDeliveryMethod",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "preferredDeliveryMethod",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "preferredDeliveryMethod",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the value for the field associated with the
   * preferredLanguage attribute, if present.
   *
   * @return  The value for the field associated with the
   *          preferredLanguage attribute, or
   *          {@code null} if the field does not have a value.
   */
  public String getPreferredLanguage()
  {
    return preferredLanguage;
  }



  /**
   * Sets the value for the field associated with the
   * preferredLanguage attribute.
   *
   * @param  v  The value for the field associated with the
   *            preferredLanguage attribute.
   */
  public void setPreferredLanguage(final String v)
  {
    this.preferredLanguage = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the preferredLanguage attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generatePreferredLanguageFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "preferredLanguage");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "preferredlanguage");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           value,
           "preferredLanguage").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "preferredLanguage");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "preferredLanguage",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "preferredLanguage",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "preferredLanguage",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "preferredLanguage",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "preferredLanguage",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "preferredLanguage",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "preferredLanguage",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * registeredAddress attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          registeredAddress attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstRegisteredAddress()
  {
    if ((registeredAddress == null) ||
        (registeredAddress.length == 0))
    {
      return null;
    }
    else
    {
      return registeredAddress[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * registeredAddress attribute, if present.
   *
   * @return  The values for the field associated with the
   *          registeredAddress attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getRegisteredAddress()
  {
    return registeredAddress;
  }



  /**
   * Sets the values for the field associated with the
   * registeredAddress attribute.
   *
   * @param  v  The values for the field associated with the
   *            registeredAddress attribute.
   */
  public void setRegisteredAddress(final String... v)
  {
    this.registeredAddress = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the registeredAddress attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateRegisteredAddressFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "registeredAddress");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "registeredaddress");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "registeredAddress").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "registeredAddress");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "registeredAddress",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "registeredAddress",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "registeredAddress",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "registeredAddress",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "registeredAddress",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "registeredAddress",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "registeredAddress",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * roomNumber attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          roomNumber attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstRoomNumber()
  {
    if ((roomNumber == null) ||
        (roomNumber.length == 0))
    {
      return null;
    }
    else
    {
      return roomNumber[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * roomNumber attribute, if present.
   *
   * @return  The values for the field associated with the
   *          roomNumber attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getRoomNumber()
  {
    return roomNumber;
  }



  /**
   * Sets the values for the field associated with the
   * roomNumber attribute.
   *
   * @param  v  The values for the field associated with the
   *            roomNumber attribute.
   */
  public void setRoomNumber(final String... v)
  {
    this.roomNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the roomNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateRoomNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "roomNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "roomnumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "roomNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "roomNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "roomNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "roomNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "roomNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "roomNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "roomNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "roomNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "roomNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * secretary attribute as a DN, if present.
   *
   * @return  The first value for the field associated with the
   *          secretary attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public DN getFirstSecretaryDN()
  {
    if ((secretary == null) ||
        (secretary.length == 0))
    {
      return null;
    }
    else
    {
      return secretary[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * secretary attribute as DNs, if present.
   *
   * @return  The values for the field associated with the
   *          secretary attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public DN[] getSecretaryDNs()
  {
    return secretary;
  }



  /**
   * Retrieves the values for the field associated with the
   * secretary attribute as objects of the specified type,
   * if present.
   *
   * @param  <T>  The type of object to return.
   *
   * @param  connection  The connection to use to retrieve the entries.  It
   *                     must not be {@code null}.
   * @param  type        The type of object as which the entries should be
   *                     decoded.  It must not be {@code null}, and the class
   *                     must be marked with the {@code LDAPObject} annotation
   *                     type.
   *
   * @return  A {@code PersistedObjects} object that may be used to iterate
   *          across the resulting objects.
   *
   * @throws  LDAPException  If the requested type cannot be used with the LDAP
   *                         SDK persistence framework.
   */
  public <T> PersistedObjects<T> getSecretaryObjects(
                                      final LDAPInterface connection,
                                      final Class<T> type)
         throws LDAPException
  {
    return PersistUtils.getEntriesAsObjects(secretary,
         type, connection);
  }



  /**
   * Sets the values for the field associated with the
   * secretary attribute.
   *
   * @param  v  The values for the field associated with the
   *            secretary attribute.
   */
  public void setSecretary(final DN... v)
  {
    this.secretary = v;
  }



  /**
   * Sets the values for the field associated with the
   * secretary attribute.
   *
   * @param  v  The string representations of the values for the field
   *            associated with the secretary attribute.
   *
   * @throws  LDAPException  If any of the provided strings cannot be parsed as
   *                         a DN.
   */
  public void setSecretary(final String... v)
         throws LDAPException
  {
    if (v == null)
    {
      this.secretary = null;
    }
    else
    {
      this.secretary = new DN[v.length];
      for (int i=0; i < v.length; i++)
      {
        this.secretary[i] = new DN(v[i]);
      }
    }
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the secretary attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateSecretaryFilter(
                            final PersistFilterType filterType,
                            final DN value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "secretary");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "secretary");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new DN[] { value },
           "secretary").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "secretary");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "secretary",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "secretary",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "secretary",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "secretary",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "secretary",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "secretary",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "secretary",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * seeAlso attribute as a DN, if present.
   *
   * @return  The first value for the field associated with the
   *          seeAlso attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public DN getFirstSeeAlsoDN()
  {
    if ((seeAlso == null) ||
        (seeAlso.length == 0))
    {
      return null;
    }
    else
    {
      return seeAlso[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * seeAlso attribute as DNs, if present.
   *
   * @return  The values for the field associated with the
   *          seeAlso attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public DN[] getSeeAlsoDNs()
  {
    return seeAlso;
  }



  /**
   * Retrieves the values for the field associated with the
   * seeAlso attribute as objects of the specified type,
   * if present.
   *
   * @param  <T>  The type of object to return.
   *
   * @param  connection  The connection to use to retrieve the entries.  It
   *                     must not be {@code null}.
   * @param  type        The type of object as which the entries should be
   *                     decoded.  It must not be {@code null}, and the class
   *                     must be marked with the {@code LDAPObject} annotation
   *                     type.
   *
   * @return  A {@code PersistedObjects} object that may be used to iterate
   *          across the resulting objects.
   *
   * @throws  LDAPException  If the requested type cannot be used with the LDAP
   *                         SDK persistence framework.
   */
  public <T> PersistedObjects<T> getSeeAlsoObjects(
                                      final LDAPInterface connection,
                                      final Class<T> type)
         throws LDAPException
  {
    return PersistUtils.getEntriesAsObjects(seeAlso,
         type, connection);
  }



  /**
   * Sets the values for the field associated with the
   * seeAlso attribute.
   *
   * @param  v  The values for the field associated with the
   *            seeAlso attribute.
   */
  public void setSeeAlso(final DN... v)
  {
    this.seeAlso = v;
  }



  /**
   * Sets the values for the field associated with the
   * seeAlso attribute.
   *
   * @param  v  The string representations of the values for the field
   *            associated with the seeAlso attribute.
   *
   * @throws  LDAPException  If any of the provided strings cannot be parsed as
   *                         a DN.
   */
  public void setSeeAlso(final String... v)
         throws LDAPException
  {
    if (v == null)
    {
      this.seeAlso = null;
    }
    else
    {
      this.seeAlso = new DN[v.length];
      for (int i=0; i < v.length; i++)
      {
        this.seeAlso[i] = new DN(v[i]);
      }
    }
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the seeAlso attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateSeeAlsoFilter(
                            final PersistFilterType filterType,
                            final DN value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "seeAlso");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "seealso");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new DN[] { value },
           "seeAlso").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "seeAlso");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "seeAlso",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "seeAlso",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "seeAlso",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "seeAlso",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "seeAlso",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "seeAlso",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "seeAlso",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * st attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          st attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstSt()
  {
    if ((st == null) ||
        (st.length == 0))
    {
      return null;
    }
    else
    {
      return st[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * st attribute, if present.
   *
   * @return  The values for the field associated with the
   *          st attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getSt()
  {
    return st;
  }



  /**
   * Sets the values for the field associated with the
   * st attribute.
   *
   * @param  v  The values for the field associated with the
   *            st attribute.
   */
  public void setSt(final String... v)
  {
    this.st = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the st attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateStFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "st");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "st");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "st").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "st");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "st",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "st",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "st",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "st",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "st",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "st",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "st",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * street attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          street attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstStreet()
  {
    if ((street == null) ||
        (street.length == 0))
    {
      return null;
    }
    else
    {
      return street[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * street attribute, if present.
   *
   * @return  The values for the field associated with the
   *          street attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getStreet()
  {
    return street;
  }



  /**
   * Sets the values for the field associated with the
   * street attribute.
   *
   * @param  v  The values for the field associated with the
   *            street attribute.
   */
  public void setStreet(final String... v)
  {
    this.street = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the street attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateStreetFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "street");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "street");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "street").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "street");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "street",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "street",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "street",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "street",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "street",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "street",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "street",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * telephoneNumber attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          telephoneNumber attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstTelephoneNumber()
  {
    if ((telephoneNumber == null) ||
        (telephoneNumber.length == 0))
    {
      return null;
    }
    else
    {
      return telephoneNumber[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * telephoneNumber attribute, if present.
   *
   * @return  The values for the field associated with the
   *          telephoneNumber attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getTelephoneNumber()
  {
    return telephoneNumber;
  }



  /**
   * Sets the values for the field associated with the
   * telephoneNumber attribute.
   *
   * @param  v  The values for the field associated with the
   *            telephoneNumber attribute.
   */
  public void setTelephoneNumber(final String... v)
  {
    this.telephoneNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the telephoneNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateTelephoneNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "telephoneNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "telephonenumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "telephoneNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "telephoneNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "telephoneNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "telephoneNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "telephoneNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "telephoneNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "telephoneNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "telephoneNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "telephoneNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * teletexTerminalIdentifier attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          teletexTerminalIdentifier attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstTeletexTerminalIdentifier()
  {
    if ((teletexTerminalIdentifier == null) ||
        (teletexTerminalIdentifier.length == 0))
    {
      return null;
    }
    else
    {
      return teletexTerminalIdentifier[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * teletexTerminalIdentifier attribute, if present.
   *
   * @return  The values for the field associated with the
   *          teletexTerminalIdentifier attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getTeletexTerminalIdentifier()
  {
    return teletexTerminalIdentifier;
  }



  /**
   * Sets the values for the field associated with the
   * teletexTerminalIdentifier attribute.
   *
   * @param  v  The values for the field associated with the
   *            teletexTerminalIdentifier attribute.
   */
  public void setTeletexTerminalIdentifier(final String... v)
  {
    this.teletexTerminalIdentifier = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the teletexTerminalIdentifier attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateTeletexTerminalIdentifierFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "teletexTerminalIdentifier");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "teletexterminalidentifier");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "teletexTerminalIdentifier").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "teletexTerminalIdentifier");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "teletexTerminalIdentifier",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "teletexTerminalIdentifier",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "teletexTerminalIdentifier",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "teletexTerminalIdentifier",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "teletexTerminalIdentifier",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "teletexTerminalIdentifier",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "teletexTerminalIdentifier",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * telexNumber attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          telexNumber attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstTelexNumber()
  {
    if ((telexNumber == null) ||
        (telexNumber.length == 0))
    {
      return null;
    }
    else
    {
      return telexNumber[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * telexNumber attribute, if present.
   *
   * @return  The values for the field associated with the
   *          telexNumber attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getTelexNumber()
  {
    return telexNumber;
  }



  /**
   * Sets the values for the field associated with the
   * telexNumber attribute.
   *
   * @param  v  The values for the field associated with the
   *            telexNumber attribute.
   */
  public void setTelexNumber(final String... v)
  {
    this.telexNumber = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the telexNumber attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateTelexNumberFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "telexNumber");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "telexnumber");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "telexNumber").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "telexNumber");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "telexNumber",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "telexNumber",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "telexNumber",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "telexNumber",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "telexNumber",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "telexNumber",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "telexNumber",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * title attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          title attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstTitle()
  {
    if ((title == null) ||
        (title.length == 0))
    {
      return null;
    }
    else
    {
      return title[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * title attribute, if present.
   *
   * @return  The values for the field associated with the
   *          title attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getTitle()
  {
    return title;
  }



  /**
   * Sets the values for the field associated with the
   * title attribute.
   *
   * @param  v  The values for the field associated with the
   *            title attribute.
   */
  public void setTitle(final String... v)
  {
    this.title = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the title attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateTitleFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "title");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "title");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "title").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "title");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "title",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "title",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "title",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "title",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "title",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "title",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "title",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * userCertificate attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          userCertificate attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public byte[] getFirstUserCertificate()
  {
    if ((userCertificate == null) ||
        (userCertificate.length == 0))
    {
      return null;
    }
    else
    {
      return userCertificate[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * userCertificate attribute, if present.
   *
   * @return  The values for the field associated with the
   *          userCertificate attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public byte[][] getUserCertificate()
  {
    return userCertificate;
  }



  /**
   * Sets the values for the field associated with the
   * userCertificate attribute.
   *
   * @param  v  The values for the field associated with the
   *            userCertificate attribute.
   */
  public void setUserCertificate(final byte[]... v)
  {
    this.userCertificate = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the userCertificate attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateUserCertificateFilter(
                            final PersistFilterType filterType,
                            final byte[] value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "userCertificate");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "usercertificate");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new byte[][] { value },
           "userCertificate").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "userCertificate");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "userCertificate",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "userCertificate",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "userCertificate",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "userCertificate",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "userCertificate",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "userCertificate",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "userCertificate",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * userPassword attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          userPassword attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstUserPassword()
  {
    if ((userPassword == null) ||
        (userPassword.length == 0))
    {
      return null;
    }
    else
    {
      return userPassword[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * userPassword attribute, if present.
   *
   * @return  The values for the field associated with the
   *          userPassword attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getUserPassword()
  {
    return userPassword;
  }



  /**
   * Sets the values for the field associated with the
   * userPassword attribute.
   *
   * @param  v  The values for the field associated with the
   *            userPassword attribute.
   */
  public void setUserPassword(final String... v)
  {
    this.userPassword = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the userPassword attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateUserPasswordFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "userPassword");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "userpassword");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "userPassword").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "userPassword");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "userPassword",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "userPassword",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "userPassword",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "userPassword",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "userPassword",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "userPassword",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "userPassword",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * userPKCS12 attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          userPKCS12 attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public byte[] getFirstUserPKCS12()
  {
    if ((userPKCS12 == null) ||
        (userPKCS12.length == 0))
    {
      return null;
    }
    else
    {
      return userPKCS12[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * userPKCS12 attribute, if present.
   *
   * @return  The values for the field associated with the
   *          userPKCS12 attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public byte[][] getUserPKCS12()
  {
    return userPKCS12;
  }



  /**
   * Sets the values for the field associated with the
   * userPKCS12 attribute.
   *
   * @param  v  The values for the field associated with the
   *            userPKCS12 attribute.
   */
  public void setUserPKCS12(final byte[]... v)
  {
    this.userPKCS12 = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the userPKCS12 attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateUserPKCS12Filter(
                            final PersistFilterType filterType,
                            final byte[] value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "userPKCS12");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "userpkcs12");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new byte[][] { value },
           "userPKCS12").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "userPKCS12");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "userPKCS12",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "userPKCS12",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "userPKCS12",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "userPKCS12",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "userPKCS12",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "userPKCS12",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "userPKCS12",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * userSMIMECertificate attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          userSMIMECertificate attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public byte[] getFirstUserSMIMECertificate()
  {
    if ((userSMIMECertificate == null) ||
        (userSMIMECertificate.length == 0))
    {
      return null;
    }
    else
    {
      return userSMIMECertificate[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * userSMIMECertificate attribute, if present.
   *
   * @return  The values for the field associated with the
   *          userSMIMECertificate attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public byte[][] getUserSMIMECertificate()
  {
    return userSMIMECertificate;
  }



  /**
   * Sets the values for the field associated with the
   * userSMIMECertificate attribute.
   *
   * @param  v  The values for the field associated with the
   *            userSMIMECertificate attribute.
   */
  public void setUserSMIMECertificate(final byte[]... v)
  {
    this.userSMIMECertificate = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the userSMIMECertificate attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateUserSMIMECertificateFilter(
                            final PersistFilterType filterType,
                            final byte[] value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "userSMIMECertificate");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "usersmimecertificate");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new byte[][] { value },
           "userSMIMECertificate").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "userSMIMECertificate");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "userSMIMECertificate",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "userSMIMECertificate",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "userSMIMECertificate",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "userSMIMECertificate",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "userSMIMECertificate",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "userSMIMECertificate",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "userSMIMECertificate",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * x121Address attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          x121Address attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstX121Address()
  {
    if ((x121Address == null) ||
        (x121Address.length == 0))
    {
      return null;
    }
    else
    {
      return x121Address[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * x121Address attribute, if present.
   *
   * @return  The values for the field associated with the
   *          x121Address attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getX121Address()
  {
    return x121Address;
  }



  /**
   * Sets the values for the field associated with the
   * x121Address attribute.
   *
   * @param  v  The values for the field associated with the
   *            x121Address attribute.
   */
  public void setX121Address(final String... v)
  {
    this.x121Address = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the x121Address attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateX121AddressFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "x121Address");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "x121address");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "x121Address").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "x121Address");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "x121Address",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "x121Address",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "x121Address",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "x121Address",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "x121Address",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "x121Address",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "x121Address",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves the first value for the field associated with the
   * x500UniqueIdentifier attribute, if present.
   *
   * @return  The first value for the field associated with the
   *          x500UniqueIdentifier attribute, or
   *          {@code null} if that attribute was not present in the entry or
   *          does not have any values.
   */
  public String getFirstX500UniqueIdentifier()
  {
    if ((x500UniqueIdentifier == null) ||
        (x500UniqueIdentifier.length == 0))
    {
      return null;
    }
    else
    {
      return x500UniqueIdentifier[0];
    }
  }



  /**
   * Retrieves the values for the field associated with the
   * x500UniqueIdentifier attribute, if present.
   *
   * @return  The values for the field associated with the
   *          x500UniqueIdentifier attribute, or
   *          {@code null} if that attribute was not present in the entry.
   */
  public String[] getX500UniqueIdentifier()
  {
    return x500UniqueIdentifier;
  }



  /**
   * Sets the values for the field associated with the
   * x500UniqueIdentifier attribute.
   *
   * @param  v  The values for the field associated with the
   *            x500UniqueIdentifier attribute.
   */
  public void setX500UniqueIdentifier(final String... v)
  {
    this.x500UniqueIdentifier = v;
  }



  /**
   * Generates a filter that may be used to search for objects of this type
   * using the x500UniqueIdentifier attribute.
   * The resulting filter may be combined with other filter elements to create a
   * more complex filter.
   *
   * @param  filterType  The type of filter to generate.
   * @param  value       The value to use to use for the filter.  It may be
   *                     {@code null} only for a filter type of
   *                     {@code PRESENCE}.
   *
   * @return  The generated search filter.
   *
   * @throws  LDAPPersistException  If a problem is encountered while attempting
   *                                to generate the filter.
   */
  public static Filter generateX500UniqueIdentifierFilter(
                            final PersistFilterType filterType,
                            final String value)
         throws LDAPPersistException
  {
    final byte[] valueBytes;
    if (filterType == PersistFilterType.PRESENCE)
    {
      valueBytes = null;
    }
    else
    {
      if (value == null)
      {
        throw new LDAPPersistException("Unable to generate a filter of type " +
             filterType.name() + " with a null value for attribute " +
             "x500UniqueIdentifier");
      }

      final LDAPObjectHandler<?> objectHandler =
           getPersister().getObjectHandler();
      final FieldInfo fieldInfo = objectHandler.getFields().get(
           "x500uniqueidentifier");

      final DefaultObjectEncoder objectEncoder = new DefaultObjectEncoder();
      valueBytes = objectEncoder.encodeFieldValue(fieldInfo.getField(),
           new String[] { value },
           "x500UniqueIdentifier").getValueByteArray();
    }

    switch (filterType)
    {
      case PRESENCE:
        return Filter.createPresenceFilter(
             "x500UniqueIdentifier");
      case EQUALITY:
        return Filter.createEqualityFilter(
             "x500UniqueIdentifier",
             valueBytes);
      case STARTS_WITH:
        return Filter.createSubstringFilter(
             "x500UniqueIdentifier",
             valueBytes, null, null);
      case ENDS_WITH:
        return Filter.createSubstringFilter(
             "x500UniqueIdentifier",
             null, null, valueBytes);
      case CONTAINS:
        return Filter.createSubstringFilter(
             "x500UniqueIdentifier",
             null, new byte[][] { valueBytes }, null);
      case GREATER_OR_EQUAL:
        return Filter.createGreaterOrEqualFilter(
             "x500UniqueIdentifier",
             valueBytes);
      case LESS_OR_EQUAL:
        return Filter.createLessOrEqualFilter(
             "x500UniqueIdentifier",
             valueBytes);
      case APPROXIMATELY_EQUAL_TO:
        return Filter.createApproximateMatchFilter(
             "x500UniqueIdentifier",
             valueBytes);
      default:
        // This should never happen.
        throw new LDAPPersistException("Unrecognized filter type " +
             filterType.name());
    }
  }



  /**
   * Retrieves a string representation of this
   * {@code TestInetOrgPerson} object.
   *
   * @return  A string representation of this
   *          {@code TestInetOrgPerson} object.
   */
  @Override()
  public String toString()
  {
    final StringBuilder buffer = new StringBuilder();
    toString(buffer);
    return buffer.toString();
  }



  /**
   * Appends a string representation of this
   * {@code TestInetOrgPerson} object
     to the provided buffer.
   *
   * @param  buffer  The buffer to which the string representation should be
   *                 appended.
   */
  public void toString(final StringBuilder buffer)
  {
    buffer.append("TestInetOrgPerson(");

    boolean appended = false;
    if (ldapEntry != null)
    {
      appended = true;
      buffer.append("entryDN='");
      buffer.append(ldapEntry.getDN());
      buffer.append('\'');
    }

    if (cn != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("cn=");
      buffer.append(Arrays.toString(cn));
    }

    if (sn != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("sn=");
      buffer.append(Arrays.toString(sn));
    }

    if (uid != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("uid=");
      buffer.append(Arrays.toString(uid));
    }

    if (audio != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("audio=");
      buffer.append(Arrays.toString(audio));
    }

    if (businessCategory != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("businessCategory=");
      buffer.append(Arrays.toString(businessCategory));
    }

    if (carLicense != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("carLicense=");
      buffer.append(Arrays.toString(carLicense));
    }

    if (departmentNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("departmentNumber=");
      buffer.append(Arrays.toString(departmentNumber));
    }

    if (description != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("description=");
      buffer.append(Arrays.toString(description));
    }

    if (destinationIndicator != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("destinationIndicator=");
      buffer.append(Arrays.toString(destinationIndicator));
    }

    if (displayName != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("displayName=");
      buffer.append(displayName);
    }

    if (employeeNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("employeeNumber=");
      buffer.append(employeeNumber);
    }

    if (employeeType != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("employeeType=");
      buffer.append(Arrays.toString(employeeType));
    }

    if (facsimileTelephoneNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("facsimileTelephoneNumber=");
      buffer.append(Arrays.toString(facsimileTelephoneNumber));
    }

    if (givenName != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("givenName=");
      buffer.append(Arrays.toString(givenName));
    }

    if (homePhone != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("homePhone=");
      buffer.append(Arrays.toString(homePhone));
    }

    if (homePostalAddress != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("homePostalAddress=");
      buffer.append(Arrays.toString(homePostalAddress));
    }

    if (initials != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("initials=");
      buffer.append(Arrays.toString(initials));
    }

    if (internationaliSDNNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("internationaliSDNNumber=");
      buffer.append(Arrays.toString(internationaliSDNNumber));
    }

    if (jpegPhoto != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("jpegPhoto=");
      buffer.append(Arrays.toString(jpegPhoto));
    }

    if (l != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("l=");
      buffer.append(Arrays.toString(l));
    }

    if (labeledURI != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("labeledURI=");
      buffer.append(Arrays.toString(labeledURI));
    }

    if (mail != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("mail=");
      buffer.append(Arrays.toString(mail));
    }

    if (manager != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("manager=");
      buffer.append(Arrays.toString(manager));
    }

    if (mobile != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("mobile=");
      buffer.append(Arrays.toString(mobile));
    }

    if (o != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("o=");
      buffer.append(Arrays.toString(o));
    }

    if (ou != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("ou=");
      buffer.append(Arrays.toString(ou));
    }

    if (pager != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("pager=");
      buffer.append(Arrays.toString(pager));
    }

    if (photo != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("photo=");
      buffer.append(Arrays.toString(photo));
    }

    if (physicalDeliveryOfficeName != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("physicalDeliveryOfficeName=");
      buffer.append(Arrays.toString(physicalDeliveryOfficeName));
    }

    if (postalAddress != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("postalAddress=");
      buffer.append(Arrays.toString(postalAddress));
    }

    if (postalCode != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("postalCode=");
      buffer.append(Arrays.toString(postalCode));
    }

    if (postOfficeBox != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("postOfficeBox=");
      buffer.append(Arrays.toString(postOfficeBox));
    }

    if (preferredDeliveryMethod != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("preferredDeliveryMethod=");
      buffer.append(preferredDeliveryMethod);
    }

    if (preferredLanguage != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("preferredLanguage=");
      buffer.append(preferredLanguage);
    }

    if (registeredAddress != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("registeredAddress=");
      buffer.append(Arrays.toString(registeredAddress));
    }

    if (roomNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("roomNumber=");
      buffer.append(Arrays.toString(roomNumber));
    }

    if (secretary != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("secretary=");
      buffer.append(Arrays.toString(secretary));
    }

    if (seeAlso != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("seeAlso=");
      buffer.append(Arrays.toString(seeAlso));
    }

    if (st != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("st=");
      buffer.append(Arrays.toString(st));
    }

    if (street != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("street=");
      buffer.append(Arrays.toString(street));
    }

    if (telephoneNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("telephoneNumber=");
      buffer.append(Arrays.toString(telephoneNumber));
    }

    if (teletexTerminalIdentifier != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("teletexTerminalIdentifier=");
      buffer.append(Arrays.toString(teletexTerminalIdentifier));
    }

    if (telexNumber != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("telexNumber=");
      buffer.append(Arrays.toString(telexNumber));
    }

    if (title != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("title=");
      buffer.append(Arrays.toString(title));
    }

    if (userCertificate != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("userCertificate=");
      buffer.append(Arrays.toString(userCertificate));
    }

    if (userPassword != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("userPassword=");
      buffer.append(Arrays.toString(userPassword));
    }

    if (userPKCS12 != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("userPKCS12=");
      buffer.append(Arrays.toString(userPKCS12));
    }

    if (userSMIMECertificate != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("userSMIMECertificate=");
      buffer.append(Arrays.toString(userSMIMECertificate));
    }

    if (x121Address != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("x121Address=");
      buffer.append(Arrays.toString(x121Address));
    }

    if (x500UniqueIdentifier != null)
    {
      if (appended)
      {
        buffer.append(", ");
      }
      appended = true;
      buffer.append("x500UniqueIdentifier=");
      buffer.append(Arrays.toString(x500UniqueIdentifier));
    }

    buffer.append(')');
  }
}

